package model;

import java.util.ArrayList;

/**
 * @author Xiaotian chang
 * 
 */
public class TradeCard {

	/**
	 * do nothing constructor.
	 */
	public TradeCard() {
	}

	/**
	 * This method takes in a player and 3 cards, checks to see whether they are
	 * tradable, and if so trades them and gives the bonus to the given player
	 * 
	 * @param player
	 *            The player making the trade
	 * @param card1
	 *            Card 1
	 * @param card2
	 *            Card 2
	 * @param card3
	 *            Card 3
	 * @return true if the three is tradable and successfully traded.
	 */
	public static boolean tradeCard(Player player, Card card1, Card card2,
			Card card3) {
		Choice tempChoice = new Choice(card1, card2, card3);
		if (!tradable(player, tempChoice)) {
			return false;
		}

		/*
		 * find out how many cards's Territory is owned by player.
		 */
		Card temp;
		temp = tempChoice.getCard1();
		if (temp.getType() != CardType.WILD
				&& temp.getTerritory().getRuler().equals(player)) {
			player.addBonus(2);
		}

		temp = tempChoice.getCard2();
		if (temp.getType() != CardType.WILD
				&& temp.getTerritory().getRuler().equals(player)) {
			player.addBonus(2);
		}

		temp = tempChoice.getCard3();
		if (temp.getType() != CardType.WILD
				&& temp.getTerritory().getRuler().equals(player)) {
			player.addBonus(2);
		}

		System.out.println(player.getCards().size());
		System.out.println(player.removeCard(card1));
		System.out.println(player.removeCard(card2));
		System.out.println(player.removeCard(card3));
		System.out.println(player.getCards().size());

		player.addBonus(player.getMap().getTradeInValue());

		if (player.getMap().getTradeInValue() < 12)
			player.getMap().setTradeInValue(
					player.getMap().getTradeInValue() + 2);

		else if (player.getMap().getTradeInValue() == 12)
			player.getMap().setTradeInValue(15);

		else if (player.getMap().getTradeInValue() < 50)
			player.getMap().setTradeInValue(
					player.getMap().getTradeInValue() + 5);

		return true;

	}

	/**
	 * Returns an array list of choice ojects of the different options a player
	 * has to trade in his/her cards
	 * 
	 * @param player
	 *            The player who owns the cards.
	 * @return true if the cards a player has can be treaded.
	 */
	public static ArrayList<Choice> tradeList(Player player) {

		ArrayList<Choice> result = new ArrayList<Choice>();
		if (player.getCards().size() < 3) {
			return result;
		} else {
			for (int i = 0; i < player.getCards().size() - 3; i++) {
				for (int j = i + 1; j < player.getCards().size() - 2; j++) {
					for (int z = j + 1; z < player.getCards().size() - 1; z++) {
						if (j > i && z > j) {

							Card card1 = player.getCards().get(i);
							Card card2 = player.getCards().get(j);
							Card card3 = player.getCards().get(z);

							Choice tempChoice = new Choice(card1, card2, card3);
							System.out.println(tempChoice.getCard1()
									.getTerritory());
							System.out.println(tempChoice.getCard2()
									.getTerritory());
							System.out.println(tempChoice.getCard3()
									.getTerritory());

							if (tradable(player, tempChoice)) {
								result.add(tempChoice);
							}
						}
					}
				}
			}
			return result;
		}
	}

	/**
	 *Decides whether a given selections of cards is tradable.
	 * 
	 * @param player
	 *            The player who owns the cards
	 * @param choice
	 *            The selection of cards
	 * @return true if the three cards in choice is able to trade.
	 */
	public static boolean tradable(Player player, Choice choice) {
		if (choice.getCard1().equals(choice.getCard2())) {
			System.out.println("working 0001");
			return false;
		}

		if (choice.getCard1().equals(choice.getCard3())) {
			System.out.println("working 0002");
			return false;
		}

		if (choice.getCard2().equals(choice.getCard3())) {
			System.out.println("working 0003");
			return false;
		}

		int numS = 0;
		int numH = 0;
		int numC = 0;
		int numW = 0;

		/*
		 * to find out whether this choice is tradable.
		 */
		if (choice.getCard1().getType() == CardType.CANNON) {
			numC++;
		}
		if (choice.getCard1().getType() == CardType.HORSE) {
			numH++;
		}
		if (choice.getCard1().getType() == CardType.SOLDIER) {
			numS++;
		}
		if (choice.getCard1().getType() == CardType.WILD) {
			numW++;
		}

		if (choice.getCard2().getType() == CardType.CANNON) {
			numC++;
		}
		if (choice.getCard2().getType() == CardType.HORSE) {
			numH++;
		}
		if (choice.getCard2().getType() == CardType.SOLDIER) {
			numS++;
		}
		if (choice.getCard2().getType() == CardType.WILD) {
			numW++;
		}

		if (choice.getCard3().getType() == CardType.CANNON) {
			numC++;
		}
		if (choice.getCard3().getType() == CardType.HORSE) {
			numH++;
		}
		if (choice.getCard3().getType() == CardType.SOLDIER) {
			numS++;
		}
		if (choice.getCard3().getType() == CardType.WILD) {
			numW++;
		}

		System.out.println(choice.getCard1().getTerritory());
		System.out.println(choice.getCard2().getTerritory());
		System.out.println(choice.getCard3().getTerritory());

		if (numW >= 1 && numS + numC + numH >= 2) {
			System.out.println("numW >= 1 && numS + numC + numH >= 2");
			return true;
		}

		if (numS == 1 && numH == 1 && numC == 1) {
			System.out.println("numS == 1 && numH == 1 && numC == 1");
			return true;
		}

		if (numS == 3) {
			System.out.println("numS == 3");
			return true;
		}
		if (numC == 3) {
			System.out.println("numC == 3");
			return true;
		}
		if (numH == 3) {
			System.out.println("numH == 3");
			return true;
		}
		return false;
	}

	/**
	 * Inner class representing a selections of 3 cards for attempting a trade
	 * 
	 * @author chang
	 * 
	 */
	public static class Choice {
		Card card1;
		Card card2;
		Card card3;

		Choice(Card card1, Card card2, Card card3) {
			this.card1 = card1;
			this.card2 = card2;
			this.card3 = card3;
		}

		/**
		 * @return the first card.
		 */
		public Card getCard1() {
			return this.card1;
		}

		/**
		 * @return the second card.
		 */
		public Card getCard2() {
			return this.card2;
		}

		/**
		 * @return the third card.
		 */
		public Card getCard3() {
			return this.card3;
		}

	}

}
